﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "UserCoordSystemMgrDlg.h"
#include <QTableWidgetItem>
#include <QString>
#include "ui_UserCoordSystemMgrDlg.h"
#include "IDocument.h"
#include "GbmpNew.h"
#include "GbmpQuickCast.h"
#include "IUserCoordinateSystem.h"
#include "IElementBasicInformation.h"
#include "IUserTransaction.h"
#include "IUserCoordinateSystemStatusManager.h"
#include "AddModifyUCSDlg.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

UserCoordSystemMgrDlg::UserCoordSystemMgrDlg(gcmp::IDocument* pDoc, QWidget *parent /*= 0*/) : QDialog(parent, Qt::Dialog)
{
    m_pDoc = pDoc;
    m_opUi = NEW_AS_OWNER_PTR(Ui::UserCoordMgrDlg);
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_opUi != nullptr, L"m_opUi为空",L"GDMPLab",L"2024-03-30");
    m_opUi->setupUi(this);

    this->connect(m_opUi->btnDelete, SIGNAL(clicked()), this, SLOT(OnDeleteUCS()));
    this->connect(m_opUi->btnAdd, SIGNAL(clicked()), this, SLOT(OnAddUCS()));
    this->connect(m_opUi->btnActivate, SIGNAL(clicked()), this, SLOT(OnActivate()));
    this->connect(m_opUi->btnModify, SIGNAL(clicked()), this, SLOT(OnModify()));

    BuildTableWidget();
}

UserCoordSystemMgrDlg::~UserCoordSystemMgrDlg()
{

}

void UserCoordSystemMgrDlg::BuildTableWidget()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc != nullptr, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");
    QTableWidget* pTableWidget = m_opUi->tableWidget;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTableWidget != nullptr, L"pTableWidget为空",L"GDMPLab",L"2024-03-30");

    pTableWidget->setColumnCount(4);
    QTableWidgetItem* pHead1 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pHead1 != nullptr, L"pHead1为空",L"GDMPLab",L"2024-03-30");
    pHead1->setText(QString::fromStdWString(GBMP_TR(L"名称")));
    pTableWidget->setHorizontalHeaderItem(0, pHead1);
    QTableWidgetItem* pHead2 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pHead2 != nullptr, L"pHead1为空",L"GDMPLab",L"2024-03-30");
    pHead2->setText(QString::fromStdWString(GBMP_TR(L"原点X")));
    pTableWidget->setHorizontalHeaderItem(1, pHead2);
    QTableWidgetItem* pHead3 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pHead3 != nullptr, L"pHead1为空",L"GDMPLab",L"2024-03-30");
    pHead3->setText(QString::fromStdWString(GBMP_TR(L"原点Y")));
    pTableWidget->setHorizontalHeaderItem(2, pHead3);
    QTableWidgetItem* pHead4 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pHead4 != nullptr, L"pHead1为空",L"GDMPLab",L"2024-03-30");
    pHead4->setText(QString::fromStdWString(GBMP_TR(L"原点Z")));
    pTableWidget->setHorizontalHeaderItem(3, pHead4);

    std::vector<gcmp::IUserCoordinateSystem*> allUCS = gcmp::IUserCoordinateSystem::GetAllUserCoordinateSystem(m_pDoc);
    if (allUCS.empty())
    {
        return;
    }
    pTableWidget->setRowCount(int(allUCS.size()));
    for (int i = 0; i<int(allUCS.size()); ++i)
    {
        gcmp::IElementBasicInformation* pBasicInfo = allUCS[i]->GetBasicInformation();
        DBG_WARN_AND_CONTINUE_UNLESS(pBasicInfo != nullptr, L"pBasicInfo为空",L"GDMPLab",L"2024-03-30");
        const gcmp::Coordinate3d& coord = allUCS[i]->GetCoordinate();
        QTableWidgetItem* pItem1 = NEW_AS_QT(QTableWidgetItem);
        DBG_WARN_AND_CONTINUE_UNLESS(pItem1 != nullptr, L"pItem1为空",L"GDMPLab",L"2024-03-30");
        pItem1->setText(QString::fromStdWString(pBasicInfo->GetName()));
        pItem1->setData(Qt::UserRole, allUCS[i]->GetElementId().AsInt64());
        pTableWidget->setItem(i, 0, pItem1);
        QTableWidgetItem* pItem2 = NEW_AS_QT(QTableWidgetItem);
        DBG_WARN_AND_CONTINUE_UNLESS(pItem2 != nullptr, L"pItem2为空",L"GDMPLab",L"2024-03-30");
        pItem2->setText(QString::number(coord.GetOrigin().X()));
        pTableWidget->setItem(i, 1, pItem2);
        QTableWidgetItem* pItem3 = NEW_AS_QT(QTableWidgetItem);
        DBG_WARN_AND_CONTINUE_UNLESS(pItem3 != nullptr, L"pItem3为空",L"GDMPLab",L"2024-03-30");
        pItem3->setText(QString::number(coord.GetOrigin().Y()));
        pTableWidget->setItem(i, 2, pItem3);
        QTableWidgetItem* pItem4 = NEW_AS_QT(QTableWidgetItem);
        DBG_WARN_AND_CONTINUE_UNLESS(pItem4 != nullptr, L"pItem4为空",L"GDMPLab",L"2024-03-30");
        pItem4->setText(QString::number(coord.GetOrigin().Z()));
        pTableWidget->setItem(i, 3, pItem4);
    }
}

void UserCoordSystemMgrDlg::OnDeleteUCS()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc != nullptr, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");
    QTableWidget* pTableWidget = m_opUi->tableWidget;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTableWidget != nullptr, L"pTableWidget为空",L"GDMPLab",L"2024-03-30");
    QList<QTableWidgetItem*> selectItems = pTableWidget->selectedItems();
    std::set<int> selectRows;
    for (int i = 0; i < selectItems.size(); ++i)
    {
        selectRows.insert(pTableWidget->row(selectItems[i]));
    }
    std::vector<gcmp::ElementId> vIdToDelete;
    std::vector<int> vRowToDelete;
    for (std::set<int>::iterator it = selectRows.begin(); it != selectRows.end(); ++it)
    {
        QTableWidgetItem* pItem = pTableWidget->item(*it, 0);
        if (pItem == nullptr)
        {
            continue;
        }
        gcmp::ElementId idToDel(Int64(pItem->data(Qt::UserRole).toLongLong()));
        gcmp::IUserCoordinateSystem* pUCS = gcmp::quick_cast<gcmp::IUserCoordinateSystem>(m_pDoc->GetElement(idToDel));
        DBG_WARN_AND_CONTINUE_UNLESS(pUCS != nullptr, L"pUCS为空",L"GDMPLab",L"2024-03-30");
        vIdToDelete.emplace_back(idToDel);
        vRowToDelete.emplace_back(*it);
    }
    gcmp::OwnerPtr<gcmp::IUserTransaction> opTransact = gcmp::IUserTransaction::Create(m_pDoc, GBMP_TR(L"删除用户坐标系"));
    DBG_WARN_AND_RETURN_VOID_UNLESS(opTransact != nullptr, L"opTransact为空",L"GDMPLab",L"2024-03-30");
    bool bOk = false;
    for (std::size_t i = 0; i < vIdToDelete.size(); ++i)
    {
        std::wstring sDeleteExplanation;
        bOk = m_pDoc->DeleteElement(vIdToDelete[i], &sDeleteExplanation);
        if (!bOk)
        {
            break;
        }
    }
    if (bOk)
    {
        for (std::size_t i = 0; i < vIdToDelete.size(); ++i)
        {
            for (int j = 0; j < pTableWidget->rowCount(); ++j)
            {
                QTableWidgetItem* pItem = pTableWidget->item(j, 0);
                if (pItem == nullptr)
                {
                    continue;
                }
                gcmp::ElementId idToDel(Int64(pItem->data(Qt::UserRole).toLongLong()));
                if (idToDel == vIdToDelete[i])
                {
                    pTableWidget->removeRow(j);
                    break;
                }
            }
        }
        opTransact->Commit();
    }
    else
    {
        opTransact->Rollback();
    }
}

void UserCoordSystemMgrDlg::OnAddUCS()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc != nullptr, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");
    QTableWidget* pTableWidget = m_opUi->tableWidget;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTableWidget != nullptr, L"pTableWidget为空",L"GDMPLab",L"2024-03-30");

    GbmpUCSAddModifyDlg dlg(GBMP_TR(L"用户坐标系"), gcmp::Coordinate3d());
    if (dlg.exec() != QDialog::Accepted)
    {
        return;
    }

    pTableWidget->insertRow(pTableWidget->rowCount());

    QTableWidgetItem* pItem1 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem1 != nullptr, L"pItem1为空",L"GDMPLab",L"2024-03-30");
    pItem1->setText(QString::fromStdWString(dlg.GetName()));
    
    pTableWidget->setItem(pTableWidget->rowCount() - 1, 0, pItem1);
    QTableWidgetItem* pItem2 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem2 != nullptr, L"pItem2为空",L"GDMPLab",L"2024-03-30");
    pItem2->setText(QString::number(dlg.GetCoordinate().GetOrigin().X()));
    pTableWidget->setItem(pTableWidget->rowCount() - 1, 1, pItem2);
    QTableWidgetItem* pItem3 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem3 != nullptr, L"pItem3为空",L"GDMPLab",L"2024-03-30");
    pItem3->setText(QString::number(dlg.GetCoordinate().GetOrigin().Y()));
    pTableWidget->setItem(pTableWidget->rowCount() - 1, 2, pItem3);
    QTableWidgetItem* pItem4 = NEW_AS_QT(QTableWidgetItem);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem4 != nullptr, L"pItem4为空",L"GDMPLab",L"2024-03-30");
    pItem4->setText(QString::number(dlg.GetCoordinate().GetOrigin().Z()));
    pTableWidget->setItem(pTableWidget->rowCount() - 1, 3, pItem4);

    gcmp::OwnerPtr<gcmp::IUserTransaction> opTransact = gcmp::IUserTransaction::Create(m_pDoc, GBMP_TR(L"添加用户坐标系"));
    DBG_WARN_AND_RETURN_VOID_UNLESS(opTransact != nullptr, L"opTransact为空",L"GDMPLab",L"2024-03-30");

    gcmp::IUserCoordinateSystem* pUCSAdd = gcmp::IUserCoordinateSystem::Create(m_pDoc, dlg.GetName(), dlg.GetCoordinate());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUCSAdd != nullptr, L"pUCSAdd为空",L"GDMPLab",L"2024-03-30");

    opTransact->Commit();

    pItem1 = pTableWidget->item(pTableWidget->rowCount() - 1, 0);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem1 != nullptr, L"pItem1为空",L"GDMPLab",L"2024-03-30");
    pItem1->setData(Qt::UserRole, pUCSAdd->GetElementId().AsInt64());
}

void UserCoordSystemMgrDlg::OnActivate()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc != nullptr, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");
    QTableWidget* pTableWidget = m_opUi->tableWidget;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTableWidget != nullptr, L"pTableWidget为空",L"GDMPLab",L"2024-03-30");
    QList<QTableWidgetItem*> selectItems = pTableWidget->selectedItems();
    std::set<int> selectRows;
    for (int i = 0; i < selectItems.size(); ++i)
    {
        selectRows.insert(pTableWidget->row(selectItems[i]));
    }
    if (selectRows.size() != 1)
    {
        return;
    }
    QTableWidgetItem* pItem = pTableWidget->item(*selectRows.begin(), 0);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem != nullptr, L"pItem为空",L"GDMPLab",L"2024-03-30");
    
    gcmp::ElementId idToDel(Int64(pItem->data(Qt::UserRole).toLongLong()));
    gcmp::IUserCoordinateSystem* pUCS = gcmp::quick_cast<gcmp::IUserCoordinateSystem>(m_pDoc->GetElement(idToDel));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUCS != nullptr, L"pUCS为空",L"GDMPLab",L"2024-03-30");

    gcmp::IUserCoordinateSystemStatusManager::ActivateUserCoordinateSystem(m_pDoc, pUCS);
}

void UserCoordSystemMgrDlg::OnModify()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc != nullptr, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");
    QTableWidget* pTableWidget = m_opUi->tableWidget;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pTableWidget != nullptr, L"pTableWidget为空",L"GDMPLab",L"2024-03-30");
    QList<QTableWidgetItem*> selectItems = pTableWidget->selectedItems();
    std::set<int> selectRows;
    for (int i = 0; i < selectItems.size(); ++i)
    {
        selectRows.insert(pTableWidget->row(selectItems[i]));
    }
    if (selectRows.size() != 1)
    {
        return;
    }

    int nRow = *selectRows.begin();
    QTableWidgetItem* pItem = pTableWidget->item(nRow, 0);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem != nullptr, L"pItem为空",L"GDMPLab",L"2024-03-30");

    gcmp::ElementId idToDel(Int64(pItem->data(Qt::UserRole).toLongLong()));
    gcmp::IUserCoordinateSystem* pUCS = gcmp::quick_cast<gcmp::IUserCoordinateSystem>(m_pDoc->GetElement(idToDel));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUCS != nullptr, L"pUCS为空",L"GDMPLab",L"2024-03-30");
    gcmp::IElementBasicInformation* pBasicInfo = pUCS->GetBasicInformation();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pBasicInfo != nullptr, L"pBasicInfo为空",L"GDMPLab",L"2024-03-30");

    GbmpUCSAddModifyDlg dlg(pBasicInfo->GetName(), pUCS->GetCoordinate());
    if (dlg.exec() != QDialog::Accepted)
    {
        return;
    }

    pItem->setText(QString::fromStdWString(dlg.GetName()));
    QTableWidgetItem* pItem2 = pTableWidget->item(nRow, 1);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem2 != nullptr, L"pItem2为空",L"GDMPLab",L"2024-03-30");
    pItem2->setText(QString::number(dlg.GetCoordinate().GetOrigin().X()));
    QTableWidgetItem* pItem3 = pTableWidget->item(nRow, 2);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem3 != nullptr, L"pItem3为空",L"GDMPLab",L"2024-03-30");
    pItem3->setText(QString::number(dlg.GetCoordinate().GetOrigin().Y()));
    QTableWidgetItem* pItem4 = pTableWidget->item(nRow, 3);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pItem4 != nullptr, L"pItem4为空",L"GDMPLab",L"2024-03-30");
    pItem4->setText(QString::number(dlg.GetCoordinate().GetOrigin().Z()));

    gcmp::OwnerPtr<gcmp::IUserTransaction> opTransact = gcmp::IUserTransaction::Create(m_pDoc, GBMP_TR(L"添加用户坐标系"));
    DBG_WARN_AND_RETURN_VOID_UNLESS(opTransact != nullptr, L"opTransact为空",L"GDMPLab",L"2024-03-30");

    pBasicInfo->SetName(dlg.GetName());
    pUCS->SetCoordinate(dlg.GetCoordinate());

    opTransact->Commit();
}
